package com.example.chatserver;

import java.io.*;
import java.net.*;
import java.util.*;

import kr.ac.kaist.swrc.jhannanum.hannanum.Workflow;
import kr.ac.kaist.swrc.jhannanum.plugin.MajorPlugin.MorphAnalyzer.ChartMorphAnalyzer.ChartMorphAnalyzer;
import kr.ac.kaist.swrc.jhannanum.plugin.MajorPlugin.PosTagger.HmmPosTagger.HMMTagger;
import kr.ac.kaist.swrc.jhannanum.plugin.SupplementPlugin.MorphemeProcessor.UnknownMorphProcessor.UnknownProcessor;
import kr.ac.kaist.swrc.jhannanum.plugin.SupplementPlugin.PlainTextProcessor.InformalSentenceFilter.InformalSentenceFilter;
import kr.ac.kaist.swrc.jhannanum.plugin.SupplementPlugin.PlainTextProcessor.SentenceSegmentor.SentenceSegmentor;
import kr.ac.kaist.swrc.jhannanum.plugin.SupplementPlugin.PosProcessor.NounExtractor.NounExtractor;

/* Chatting Server Thread */
public class ChatServerThread extends Thread {
	private static List<ChatServerThread> threads = new ArrayList<ChatServerThread>(); // Thread
	private Socket socket; // Socket

	public ChatServerThread(Socket socket) {
		super();
		this.socket = socket;
		threads.add(this);
	}

	public static String KeyLocation = "#LCT";
	public static String KeyNickname = "#NCK";
	public static String KeyRoomMake = "#RMK";
	public static String KeyDisconnect = "#DCN";
	public static String KeyMessage = "#MSG";
	public static String KeyRoomJoin = "#RJN";

	public void run() {
		InputStream in = null;
		String message;
		int size;
		byte[] buffer = new byte[1024];
		try {
			in = socket.getInputStream();
			while (true) {
				try {
					size = in.read(buffer);

					if (size <= 0)
						throw new IOException();

					message = new String(buffer, 0, size, "UTF8");

					StringTokenizer seperation = new StringTokenizer(message,
							",");
					String keyCode = seperation.nextToken();

					if (keyCode.equals(KeyMessage)) {
						// runtime error: KeyMessage 만 있을 경우 에러발생되는 것 수정 -
						// yjpark
						try {
							if (seperation.hasMoreTokens())
								sendMessageAll(seperation.nextToken());
						} catch (NoSuchElementException e) {
						}
					}

					System.err.print(message + " send!");
				} catch (IOException e) {
					socket.close();
					threads.remove(this);
					return;
				}
			}
		} catch (IOException e) {
			System.err.println(e);
		}
	}

	public void sendMessageAll(String message) {
		Workflow workflow = new Workflow();

		try {
			/* Setting up the work flow */
			/* Phase1. Supplement Plug-in for analyzing the plain text */
			workflow.appendPlainTextProcessor(new SentenceSegmentor(), null);
			workflow.appendPlainTextProcessor(new InformalSentenceFilter(),
					null);

			/*
			 * Phase2. Morphological Analyzer Plug-in and Supplement Plug-in for
			 * post processing
			 */
			workflow.setMorphAnalyzer(new ChartMorphAnalyzer(),
					"conf/plugin/MajorPlugin/MorphAnalyzer/ChartMorphAnalyzer.json");
			workflow.appendMorphemeProcessor(new UnknownProcessor(), null);

			/*
			 * For simpler morphological analysis result with 22 tags, decomment
			 * the following line. Notice: If you use SimpleMAResult22 plug-in,
			 * POSTagger will not work correctly. So don't add phase3 plug-ins
			 * after SimpleMAResult22.
			 */
			// workflow.appendMorphemeProcessor(new SimpleMAResult22(), null);

			/*
			 * For simpler morphological analysis result with 9 tags, decomment
			 * the following line. Notice: If you use SimpleMAResult09 plug-in,
			 * POSTagger will not work correctly. So don't add phase3 plug-ins
			 * after SimpleMAResult09.
			 */
			// workflow.appendMorphemeProcessor(new SimpleMAResult09(), null);

			/*
			 * Phase3. Part Of Speech Tagger Plug-in and Supplement Plug-in for
			 * post processing
			 */
//			workflow.setPosTagger(new HMMTagger(),
//					"conf/plugin/MajorPlugin/PosTagger/HmmPosTagger.json");

			/* For extracting nouns only, decomment the following line. */
//			workflow.appendPosProcessor(new NounExtractor(), null);

			/*
			 * For simpler POS tagging result with 22 tags, decomment the
			 * following line.
			 */
			// workflow.appendPosProcessor(new SimplePOSResult22(), null);

			/*
			 * For simpler POS tagging result with 9 tags, decomment the
			 * following line.
			 */
			// workflow.appendPosProcessor(new SimplePOSResult09(), null);

			/* Activate the work flow in the thread mode */
			workflow.activateWorkflow(true);

			/* Analysis using the work flow */
//			String document = "한나눔 형태소 분석기는 KLDP에서 제공하는 공개 소프트웨어 프로젝트 사이트에 등록되어 있다.";
			String document = message;

			workflow.analyze(document);

			String getResultOfDocument = workflow.getResultOfDocument();
			
			System.out.println("=================");
			System.out.println(getResultOfDocument);
			System.out.println("-----------------");
			ExtractWorkflow extractWorkflow = new ExtractWorkflow();
			ArrayList<String> extractList = extractWorkflow.test(getResultOfDocument);
			
//			message = "";
			ListIterator<String> it = extractList.listIterator();
//			while(it.hasNext())
//				message += it.next()+" ";
			System.out.println(message);
			System.out.println("=================");
			
			/* Once a work flow is activated, it can be used repeatedly. */
//			document = "日時: 2010년 7월 30일 오후 1시\n"
//					+ "場所: Coex Conference Room\n";

//			workflow.analyze(document);
//			System.out.println(workflow.getResultOfDocument());

			/* Close the work flow */
			workflow.close();

		} catch (FileNotFoundException e) {
			e.printStackTrace();
//			System.exit(0);
		} catch (IOException e) {
			e.printStackTrace();
//			System.exit(0);
		} catch (Exception e) {
			e.printStackTrace();
		}

		/* Shutdown the workflow */
		workflow.close();

		
//		message = workflow.getResultOfDocument();
		
		ChatServerThread thread;
		for (int i = 0; i < threads.size(); i++) {
			thread = (ChatServerThread) threads.get(i);
			if (thread.isAlive())
				thread.sendMessage(this, message);
		}
		System.out.println(message);
	}

	public void sendMessage(ChatServerThread talker, String message) {
		try {
			OutputStream out = socket.getOutputStream();
			String data = KeyMessage + "," + message;
			byte[] buffer = data.getBytes("UTF8");
			out.write(buffer);
			out.flush();
		} catch (IOException e) {
		}
	}
}